package cn.xeblog.plugin.game.landlords;

import cn.xeblog.commons.entity.game.landlords.Poker;
import cn.xeblog.commons.entity.game.landlords.PokerInfo;
import lombok.Getter;
import lombok.Setter;

import java.util.*;

/**
 * 玩家行为 抽象类
 *
 * @author anlingyi
 * @date 2022/6/3 2:38 下午
 */
public abstract class PlayerAction {

  /**
   * 手牌
   */
  @Setter
  @Getter
  protected List<Poker> pokers;

  /**
   * 玩家节点
   */
  protected PlayerNode playerNode;

  /**
   * 构造
   *
   * @param playerNode 玩家节点
   */
  public PlayerAction(PlayerNode playerNode) {
    this.playerNode = playerNode;
  }

  /**
   * 设置底牌
   *
   * @param lastPokers 底牌
   */
  public void setLastPokers(List<Poker> lastPokers) {
    // 没有手牌，跳过
    if (this.pokers == null) {
      return;
    }
    // 设置底牌
    this.pokers.addAll(lastPokers);
  }

  /**
   * 叫分
   *
   * @param score 上一玩家叫分
   * @return 0~3分
   */
  public abstract int callScore(int score);

  /**
   * 出牌
   *
   * @param outPlayer 出牌人
   * @param pokerInfo 出牌信息
   * @return null表示不出牌
   */
  protected PokerInfo outPoker(PlayerNode outPlayer, PokerInfo pokerInfo) {
    // 出牌
    PokerInfo out = getOutPoker(outPlayer, pokerInfo);
    // 为空表示过
    if (out == null) {
      return null;
    }

    // 当前手牌移除出牌的扑克
    this.pokers.removeAll(out.getPokers());

    return out;
  }

  /**
   * 获取出牌信息
   *
   * @param outPlayer 出牌人
   * @param pokerInfo 出牌信息
   * @return 出牌的扑克信息
   */
  protected PokerInfo getOutPoker(PlayerNode outPlayer, PokerInfo pokerInfo) {
    // 出牌人不为空且出牌人等于当前玩家，即：“过”
    if (outPlayer != null && outPlayer == playerNode) {
      outPlayer = null;
      pokerInfo = null;
    }

    // 出牌
    PokerInfo out = processOutPoker(outPlayer, pokerInfo);
    // 为空表示过
    if (out == null) {
      return null;
    }

    // 设置扑克牌列表
    out.setPokers(new ArrayList<>(out.getPokers()));
    return out;
  }

  /**
   * 出牌处理
   *
   * @param outPlayer 出牌人
   * @param pokerInfo 出牌信息
   * @return null表示不出牌
   */
  public abstract PokerInfo processOutPoker(PlayerNode outPlayer, PokerInfo pokerInfo);

}
